﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Text.RegularExpressions;

namespace VideoSearch
{
    public partial class MainForm : Form
    {
        //数据库连接
        string sConnStr;
        SqlConnection odcConnection;
        SqlCommand odCommand;

        //当前选择的文件夹
        string sSelectPath;

        //检索的文件类型
        string sFileType;

        //文件存在时是否提示
        bool bExist;

        //最少视频长度，少于这个的不添加
        int iMinLength;

        //计数
        //遍历文件数
        int iFileCount;

        //遍历文件夹数
        int iDirCount;

        //视频文件数
        int iFlvCount;

        //添加失败数
        int iFailCount;

        public MainForm()
        {
            InitializeComponent();
            //从程序所在的文件夹开始
            sSelectPath = Application.StartupPath;
        }

        private void btSelectPath_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.SelectedPath = sSelectPath;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                tbVideoPath.Text = folderBrowserDialog1.SelectedPath;
                sSelectPath = tbVideoPath.Text;
            }
        }


        private void btStart_Click(object sender, EventArgs ea)
        {
            if (tbVideoPath.Text == "")
            {
                MessageBox.Show("请先选择视频目录！");
                return;
            }

            tbMessage.Text = "";
            sFileType = tbExt.Text;
            bExist = cbExist.Checked;
            iMinLength = Convert.ToInt16(tbMinLength.Text);
            iFileCount = 0;
            iDirCount = 0;
            iFlvCount = 0;
            iFailCount = 0;

            sConnStr = tbConnStr.Text;
            //数据库连接
            odcConnection = new SqlConnection(sConnStr);
            odcConnection.Open();
            odCommand = odcConnection.CreateCommand();

            //取得当前文件夹名称
            int index = tbVideoPath.Text.LastIndexOf(@"\");
            string dirname = tbVideoPath.Text.Substring(index + 1, tbVideoPath.Text.Length - index - 1).ToLower();

            DateTime startTime = DateTime.Now;
            tbMessage.Text += startTime.ToString() + "\r\n";

            searchFlv(tbVideoPath.Text + @"\", 0, dirname);

            DateTime endTime = DateTime.Now;
            TimeSpan ts = endTime.Subtract(startTime);

            string sTimeStr = "用时" + ts.Minutes.ToString() + "分" + ts.Seconds.ToString() + "秒";
            tbMessage.Text += sTimeStr + "\r\n\r\n";

            StreamWriter sw = new StreamWriter("log.txt", true);
            sw.WriteLine(tbMessage.Text);
            sw.Close();

            MessageBox.Show("编目已完成！" + sTimeStr);

            odcConnection.Close();
            odCommand.Dispose();
            odcConnection.Dispose();

        }
        /// <summary>
        /// 搜索视频
        /// </summary>
        /// <param name="sSearchPath">当前搜索的文件夹全路径</param>
        /// <param name="iDirectoryID">当前搜索的目录ID，根目录时为0</param>
        /// <param name="sDirectoryName">当前搜索的文件夹名称</param>
        private void searchFlv(string sSearchPath, int iDirectoryID, string sDirectoryName)
        {
            //设置检索条件
            try
            {
                FileDirectoryEnumerator e = new FileDirectoryEnumerator();

                e.ReturnStringType = true;
                e.SearchForDirectory = true;
                e.SearchForFile = true;
                e.SearchPath = sSearchPath;

                while (e.MoveNext())
                {

                    this.Update();
                    if (e.IsFile)
                    {
                        //  tbMessage.Text += e.Name + "\r\n";
                        //如果文件类型符合，添加到数据库。
                        iFileCount++;

                        if (Path.GetExtension(e.Name) == sFileType)
                        {
                            iFlvCount++;
                            int iVideoLength = (int)FlvMetaDataReader.GetFlvMetaInfo(sSearchPath + e.Name).Duration;
                            if (iVideoLength > iMinLength)
                            {
                                odCommand.CommandText = "insert into [spw_Videos]([Video_Name],[Video_DirName],[Video_DirID],[Video_Length],[Video_Path]) select '" + Path.GetFileNameWithoutExtension(e.Name) + "','" + sDirectoryName + "'," + iDirectoryID + "," + iVideoLength;
                                odCommand.CommandText += " ,'" + sSearchPath + e.Name + "' where not exists (select * from [spw_Videos] where [Video_Path]='" + sSearchPath + e.Name + "')";
                                int row = odCommand.ExecuteNonQuery();

                                if (row != 1 && bExist)
                                {
                                    tbMessage.Text += sSearchPath + e.Name + "添加失败，可能已经存在\r\n";
                                    iFailCount++;
                                }

                            }
                            else
                            {
                                tbMessage.Text += sSearchPath + e.Name + "的时间长度为" + iVideoLength + "，请检查视频文件。\r\n";
                                iFailCount++;
                            }

                        }

                    }
                    else
                    {
                        iDirCount++;
                        int iChildID = getDirectoryID(e.Name, iDirectoryID);
                        searchFlv(sSearchPath + e.Name + @"\", iChildID, e.Name);
                    }
                    slStatus.Text = "文件数：" + iFileCount + "，文件夹：" + iDirCount + "，视频数：" + iFlvCount + "，失败数：" + iFailCount;
                }
                e.Close();
            }
            catch (Exception e)
            {
                tbMessage.Text += "searchFlv" + e.Message + "\r\n";
            }
        }
        /// <summary>
        /// 从数据库中检索指定文件夹的ID
        /// </summary>
        /// <param name="sDirectoryName">文件夹名称</param>
        /// <param name="iParentDirID">这个文件夹的上层文件夹ID</param>
        /// <returns>文件夹得ID</returns>
        private int getDirectoryID(string sDirectoryName, int iParentDirID)
        {
            try
            {
                odCommand.CommandText = "insert into [spw_Dir]([Dir_Name],[Dir_Parent])  select @dirname,@parentid where not exists (select * from [spw_Dir] where [Dir_Name]=@dirname and [Dir_Parent]=@parentid)";
                odCommand.Parameters.Clear();
                odCommand.Parameters.Add("@dirname", SqlDbType.NVarChar);
                odCommand.Parameters.Add("@parentid", SqlDbType.Int);
                odCommand.Parameters["@dirname"].Value = sDirectoryName;
                odCommand.Parameters["@parentid"].Value = iParentDirID;
                odCommand.ExecuteNonQuery();

                odCommand.CommandText = "select [Dir_ID] from [spw_Dir] where [Dir_Name]=@dirname and [Dir_Parent]=@parentid";
                return (int)odCommand.ExecuteScalar();
            }
            catch (Exception e)
            {
                tbMessage.Text += "getDirectoryID" + e.Message + "\r\n";
                return 0;
            }

        }
        /// <summary>
        /// 按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBuildXML_Click(object sender, EventArgs e)
        {
            string sXMLStr = "";

            sConnStr = tbConnStr.Text;

            sXMLStr += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
            sXMLStr += "<DirNode dirname=\"" + tbSiteName.Text + "\" dirid=\"0\">\n";
            sXMLStr += buildXML(0);
            sXMLStr += "</DirNode>\n";

            StreamWriter sw = new StreamWriter("Directory.XML", true);
            sw.WriteLine(sXMLStr);
            sw.Close();

            MessageBox.Show("成功生成XML文件！");

        }

        /// <summary>
        /// 迭代建立XML文档
        /// </summary>
        /// <param name="iParentID"></param>
        /// <returns></returns>
        private string buildXML(int iParentID)
        {
            string sXMLStr = "";
            using (SqlConnection odcConnection = new SqlConnection(sConnStr))
            {
                odcConnection.Open();
                using (SqlCommand odCommand = odcConnection.CreateCommand())
                {
                    odCommand.CommandText = "select [Dir_ID],[Dir_Name] from [spw_Dir]  where [Dir_Parent]=" + iParentID + " order by [Dir_Name]";

                    using (SqlDataReader sdr = odCommand.ExecuteReader())
                    {
                        while (sdr.Read())
                        {
                            int dir_id = (int)sdr.GetValue(0);
                            string dir_name = sdr.GetValue(1).ToString();
                            sXMLStr += "<DirNode dirname=\"" + dir_name + "\" dirid=\"" + dir_id + "\">\n";
                            sXMLStr += buildXML(dir_id);
                            sXMLStr += "</DirNode>\n";
                        }
                    }
                }
            }
            return sXMLStr;
        }

        private void tbMinLength_TextChanged(object sender, EventArgs e)
        {
            if (!IsInt(tbMinLength.Text))
            {
                MessageBox.Show("必须输入一个正整数。");
                tbMinLength.SelectAll();
                tbMinLength.Focus();
            }
        }
        //判断是否为正整数
        public static bool IsInt(string inString)
        {
            Regex regex = new Regex("^[0-9]*[1-9][0-9]*$");
            return regex.IsMatch(inString.Trim());
        }

        private void btGroup_Click(object sender, EventArgs e)
        {
            string sXMLStr = "";
            string sDirGroup = "";
            sConnStr = tbConnStr.Text;
            using (SqlConnection odcConnection = new SqlConnection(sConnStr))
            {
                odcConnection.Open();
                using (SqlCommand odCommand = odcConnection.CreateCommand())
                {
                    odCommand.CommandText = "select [Dir_ID],[Dir_Name],[Dir_Group] from [spw_Dir]  where  [Dir_Group] is not null order by [Dir_Group] ";

                    using (SqlDataReader sdr = odCommand.ExecuteReader())
                    {
                        while (sdr.Read())
                        {

                            int dir_id = (int)sdr.GetValue(0);
                            string dir_name = sdr.GetValue(1).ToString();
                            string dir_group = sdr.GetValue(2).ToString();

                            if (dir_group != sDirGroup)
                            {
                                //如果有内容的，那么保存起来

                                if (sXMLStr != "")
                                {
                                    sXMLStr += "</DirNode>\n";
                                    StreamWriter sw = new StreamWriter("Directory_" + sDirGroup + ".xml", false);
                                    sw.WriteLine(sXMLStr);
                                    sw.Close();
                                }
                                //然后为下一个做准备
                                sDirGroup = dir_group;
                                sXMLStr = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
                                sXMLStr += "<DirNode dirname=\"目录\" dirid=\"0\">\n";

                            }
                            sXMLStr += "<DirNode dirname=\"" + dir_name + "\" dirid=\"" + dir_id + "\">\n";
                            sXMLStr += buildXML(dir_id);
                            sXMLStr += "</DirNode>\n";
                        }
                        if (sDirGroup != "" && sXMLStr != "")
                        {
                            sXMLStr += "</DirNode>\n";
                            StreamWriter sw = new StreamWriter("Directory_" + sDirGroup + ".xml", false);
                            sw.WriteLine(sXMLStr);
                            sw.Close();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 文件搜索按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void btFile_Click(object sender, EventArgs e)
        {
            if (tbVideoPath.Text == "")
            {
                MessageBox.Show("请先选择视频目录！");
                return;
            }

            tbMessage.Text = "";
            sFileType = tbFileExt.Text;  //文件后缀
            bExist = cbExist.Checked;

            iFileCount = 0;
            iDirCount = 0;
            iFlvCount = 0;
            iFailCount = 0;

            sConnStr = tbConnStr.Text;
            //数据库连接
            odcConnection = new SqlConnection(sConnStr);
            odcConnection.Open();
            odCommand = odcConnection.CreateCommand();

            //取得当前文件夹名称
            int index = tbVideoPath.Text.LastIndexOf(@"\");
            string dirname = tbVideoPath.Text.Substring(index + 1, tbVideoPath.Text.Length - index - 1).ToLower();

            DateTime startTime = DateTime.Now;
            tbMessage.Text += startTime.ToString() + "\r\n";

            searchFile(tbVideoPath.Text + @"\", 0, dirname);



            DateTime endTime = DateTime.Now;
            TimeSpan ts = endTime.Subtract(startTime);

            string sTimeStr = "用时" + ts.Minutes.ToString() + "分" + ts.Seconds.ToString() + "秒";
            tbMessage.Text += sTimeStr + "\r\n\r\n";

            StreamWriter sw = new StreamWriter("log.txt", true);
            sw.WriteLine(tbMessage.Text);
            sw.Close();

            MessageBox.Show("编目已完成！" + sTimeStr);

            odcConnection.Close();
            odCommand.Dispose();
            odcConnection.Dispose();
        }
        /// <summary>
        /// 搜索视频
        /// </summary>
        /// <param name="sSearchPath">当前搜索的文件夹全路径</param>
        /// <param name="iDirectoryID">当前搜索的目录ID，根目录时为0</param>
        /// <param name="sDirectoryName">当前搜索的文件夹名称</param>
        private void searchFile(string sSearchPath, int iDirectoryID, string sDirectoryName)
        {
            //设置检索条件
            try
            {
                FileDirectoryEnumerator e = new FileDirectoryEnumerator();

                e.ReturnStringType = true;
                e.SearchForDirectory = true;
                e.SearchForFile = true;
                e.SearchPath = sSearchPath;

                while (e.MoveNext())
                {

                    this.Update();
                    if (e.IsFile)
                    {
                        //  tbMessage.Text += e.Name + "\r\n";
                        //如果文件类型符合，添加到数据库。
                        iFileCount++;
                        string sFileExt = Path.GetExtension(e.Name);
                        string[] sArry = sFileType.Split('|');
                        if (fileTypeCheck(sArry, sFileExt))
                        {

                            long iFileSize = e.FileLength / 1024;
                            iFlvCount++;
                            odCommand.CommandText = "insert into [spw_Videos]([Video_Name],[Video_DirName],[Video_DirID],[Video_Length],[Video_Path]) select '" + Path.GetFileNameWithoutExtension(e.Name) + "','" + sDirectoryName + "'," + iDirectoryID + "," + iFileSize;
                            odCommand.CommandText += " ,'" + sSearchPath + e.Name + "' where not exists (select * from [spw_Videos] where [Video_Path]='" + sSearchPath + e.Name + "')";
                            int row = odCommand.ExecuteNonQuery();

                            if (row != 1 && bExist)
                            {
                                tbMessage.Text += sSearchPath + e.Name + "添加失败，可能已经存在\r\n";
                                iFailCount++;
                            }
                        }

                    }
                    else
                    {
                        iDirCount++;
                        int iChildID = getDirectoryID(e.Name, iDirectoryID);
                        searchFile(sSearchPath + e.Name + @"\", iChildID, e.Name);
                    }
                    slStatus.Text = "文件数：" + iFileCount + "，文件夹：" + iDirCount + "，失败数：" + iFailCount;
                }
                e.Close();
            }
            catch (Exception e)
            {
                tbMessage.Text += "searchFile" + e.Message + "\r\n";
            }
        }
        private bool fileTypeCheck(string[] sAllowType, string sFileType)
        {
            bool bReturnValue = false;
            for (int i = 0; i < sAllowType.Length; i++)
            {
                if (sAllowType[i] == sFileType)
                {
                    bReturnValue = true;
                    break;
                }
            }
            return bReturnValue;
        }
    }
}